package qeug.shsh.task;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.args.AfterOperationArgs;
import kd.bos.exception.KDException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import org.springframework.util.Base64Utils;
import qeug.shsh.helper.FacadeHelper;
import qeug.shsh.task.taskInfo.SupplierInfo;
import qeug.shsh.task.taskInfo.UnitBankList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

// 供应商审核通过后同步至MDM
public class SupplierMDMOp extends AbstractOperationServicePlugIn {
    private static final Log log1 = LogFactory.getLog(SupplierMDMOp.class);

    String heart = "{\n" +
            "    \"Busid\": \"59003e0b2aab41378f9bbbdf0ef46cbc\",\n" +
            "    \"Appid\": \"PRD800\",\n" +
            "    \"Appname\": \"调用系统\",\n" +
            "    \"Ip\": \"10.14.13.40\",\n" +
            "    \"Userid\": \"50101010\",\n" +
            "    \"Version\": \"version1.0\",\n" +
            "    \"Isencryption\": \"1\",\n" +
            "    \"Encryptiontype\": \"Base64\",\n" +
            "    \"Iscompression\": \"0\",\n" +
            "    \"Compressiontype\": \"\",\n" +
            "    \"Mainstring\": \"" +
            "<?xml version=\\\"1.0\\\" encoding=\\\"utf-16\\\"?>\\n" +
            "<Xml_Format xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\">\\n";//报文头

    String last = "</Xml_Format>\",\n" +
            "    \"Mainformart\": \"1\",\n" +
            "    \"Remark\": \"测试系统备注\",\n" +
            "    \"Serviceappid\": \"TEST01\",\n" +
            "    \"Serviceappname\": \"测试系统\",\n" +
            "    \"Serviceusername\": \"\",\n" +
            "    \"Servicepassword\": \"\",\n" +
            "    \"Servicemodule\": \"MDM_RRE_0010\",\n" +
            "    \"Servicemodulename\": \"供应商注册\"\n" +
            "}"; // 报文尾

    @Override
    public void afterExecuteOperationTransaction(AfterOperationArgs evt) throws KDException {
        super.afterExecuteOperationTransaction(evt);
        //在费控审核通过的单据自动同步至MDM
        String mdm_url = System.getProperty("mdm.url");
        String basicAuthUserName = System.getProperty("mdm.user");//名字
        String basicAuthPassword = System.getProperty("mdm.password");//编码

        DynamicObject[] dataEntities = evt.getDataEntities();//多条数据
        for (DynamicObject dataEntity : dataEntities) {
            //日志
            HashMap<String, Object> log = new HashMap<>();
            log.put("operationModule", "供应商同步MDM");
            log.put("url", mdm_url);
            log.put("user", basicAuthUserName);
            log.put("mode", "POST");
            log.put("action", "");
            log.put("opdate", new Date());
            String Xml = "";//同步中MDM的xml报文
            Long id = dataEntity.getLong("id");
            DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle("bd_supplier", new QFilter[]{
                    new QFilter("id", QCP.equals, id)});//供应商

            SupplierInfo supplierInfo = new SupplierInfo();//主数据
            List<UnitBankList> unitBankLists = new ArrayList<>();//银行分录

            String number = dynamicObject.getString("number");//编码
            String name = dynamicObject.getString("name");//名称
            Date modifytime = dynamicObject.getDate("modifytime");//修改时间
            Date qeug_importtime = dynamicObject.getDate("qeug_importtime");//同步时间
            if (qeug_importtime != null && modifytime.before(qeug_importtime)) {
                //已经同步过的单据，修改时间在同步时间之前，则跳过
                continue;
            }else if (qeug_importtime != null){
                // 同步过的单据，修改时间在同步时间之后，修改单据
                supplierInfo.setOU_CODE(number);//供应商编码
                supplierInfo.setCHECKTYPE("2");//1：新增，2:编辑，3启用 4冻结
            }else{
                //未同步过的单据，则新增单据
                supplierInfo.setOU_CODE("");//供应商编码
                supplierInfo.setCHECKTYPE("1");//1：新增，2:编辑，3启用 4冻结
            }

            String email = dynamicObject.getString("postal_code");//电子邮箱
            String societycreditcode = dynamicObject.getString("societycreditcode");//统一社会信用代码
            String bizpartner_address = dynamicObject.getString("bizpartner_address");//详细地址
            String bizpartner_phone = dynamicObject.getString("bizpartner_phone");//联系电话
            String bizpartner_fax = dynamicObject.getString("bizpartner_fax");//传真
            String qeug_isylgys = dynamicObject.getString("qeug_isylgys");//是否原料供应商
            DynamicObject group = dynamicObject.getDynamicObject("group");//供应商分组
            String groupNumber = group.getString("number");
            DynamicObject qeug_assistantfield1 = dynamicObject.getDynamicObject("qeug_assistantfield1");//国家
            if (qeug_assistantfield1 != null) {
                supplierInfo.setOU_COUNTRY(qeug_assistantfield1.getString("name"));
            }
            DynamicObject qeug_assistantfield = dynamicObject.getDynamicObject("qeug_assistantfield");//地区
            if (qeug_assistantfield != null) {
                supplierInfo.setOU_AREA(qeug_assistantfield.getString("name"));
            }
            DynamicObject qeug_admindivision = dynamicObject.getDynamicObject("qeug_admindivision");//行政区划
            if (qeug_admindivision != null) {
                supplierInfo.setOU_CITY(qeug_admindivision.getString("name"));
            }

            String type = dynamicObject.getString("type");//伙伴类型
            if ("4".equals(type)) {
                //员工类型供应商
                supplierInfo.setOU_GSDJH("");//工商登记证号
                supplierInfo.setOU_ZZJGM("");//组织机构证号
                supplierInfo.setOU_SWDJH("");//税务登记证号
                supplierInfo.setOU_TYSHXYDM("");//统一信用代码证
                supplierInfo.setOU_GRYXZJH(societycreditcode);//个人有限证件号
            }else {
                //公司类型的供应商
                supplierInfo.setOU_GSDJH(societycreditcode);//工商登记证号
                supplierInfo.setOU_ZZJGM(societycreditcode);//组织机构证号
                supplierInfo.setOU_SWDJH(societycreditcode);//税务登记证号
                supplierInfo.setOU_TYSHXYDM(societycreditcode);//统一信用代码证
                supplierInfo.setOU_GRYXZJH("");//个人有限证件号
            }

            supplierInfo.setOU_FULLNAME(name + number);//单位全称
            supplierInfo.setOU_SHORTNAME(name + number);//单位简称
            supplierInfo.setOU_ADDRESS(bizpartner_address);//地址
            supplierInfo.setOU_TEL(bizpartner_phone);//电话
            supplierInfo.setOU_FAX(bizpartner_fax);//传真
            supplierInfo.setOU_EMAIL(email);//电子邮箱
            supplierInfo.setOU_ISMATERIAL(qeug_isylgys);//是否原料供应商
            supplierInfo.setOU_PROVIDERGROUP(groupNumber);//供应商分类编码
            supplierInfo.setOU_POSTCODE("222000");//邮编
            supplierInfo.setOU_DWXZ("");//单位性质
            supplierInfo.setOU_MYHB("");//贸易伙伴

            DynamicObjectCollection entry_bank = dynamicObject.getDynamicObjectCollection("entry_bank");//银行信息分录
            for (DynamicObject bank : entry_bank) {
                UnitBankList unitBankList = new UnitBankList();

                unitBankList.setBANK_ACCOUNT(bank.getString("bankaccount"));//银行账号
                unitBankList.setBANK_ACCOUNT_NAME(bank.getString("accountname"));//账户名称
                unitBankList.setBANK_CODE(bank.getDynamicObject("bank").getString("number"));//联行号
                unitBankList.setBANK_NAME(bank.getDynamicObject("bank").getString("name"));//开户银行名称
                unitBankList.setBANK_CURRENCY(bank.getDynamicObject("currency").getString("name"));//币种

                unitBankLists.add(unitBankList);
            }
            supplierInfo.setUnitBankLists(unitBankLists);

            try {
                Xml = getXmlWithoutHeader(supplierInfo);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            Xml = heart +
                    Xml.replace("\"", "\\\"")  // 转义 XML 中的双引号
                            .replace("\n", "\\n")   // 转义换行符
                            .replace("\r", "") +    // 去除回车符
                    last;
            log1.info("供应商注册接收到的发送报文：" + Xml);
            log.put("mainstring", Xml);

            String basic = basicAuthUserName + ":" + basicAuthPassword;
            String encoding = Base64Utils.encodeToString(basic.getBytes(StandardCharsets.UTF_8));

            String supJson = HttpRequest.post(mdm_url)
                    .header("Authorization", "Basic " + encoding)
                    .body(Xml)
                    .execute().body();

            log1.info("供应商注册接收到的反回报文：" + supJson);
            JSONObject jsonObject = JSONObject.parseObject(supJson);
            String xmlResponse = jsonObject.getString("response");//获取正常信息
            if (xmlResponse == null) {
                //未获取到正常信息，获取异常信息
                xmlResponse = jsonObject.getString("error");//获取失败信息
            }
            String xmlJson = FacadeHelper.xmlJson(xmlResponse);
            if (xmlJson == null) {
                //进入说明说明xml报文未解析成功，直接返回xml报文
                xmlJson = xmlResponse;
                log1.info("供应商注册解析后的返回报文：" + xmlResponse);
                log.put("responsebody", xmlResponse);
            } else {
                log1.info("供应商注册解析后的返回报文：" + xmlJson);
                log.put("responsebody", xmlJson);
            }

            JSONObject xmlJsonObject = JSONObject.parseObject(xmlJson);
            JSONObject backinfo = xmlJsonObject.getJSONObject("BACKINFO");

            if (backinfo != null) {
                String status = backinfo.getString("STATUS");
                String msg = backinfo.getString("MSG");
                String code = backinfo.getString("CODE");
                if ("S".equals(status)) { // 成功
                    // 反写供应商数据
                    log.put("pdesc", "成功");
                    FacadeHelper.apiLog(log);
                    dynamicObject.set("number", code);//供应商编码
                    dynamicObject.set("qeug_importtime", new Date());//同步时间
                    dynamicObject.set("qeug_reson", "");//清空同步失败原因字段
                    SaveServiceHelper.saveOperate("save", "bd_supplier", new DynamicObject[]{dynamicObject}, OperateOption.create());
                } else { // 失败
                    log.put("pdesc", "失败");
                    FacadeHelper.apiLog(log);
                    dynamicObject.set("qeug_reson", msg);
                    SaveServiceHelper.saveOperate("save", "bd_supplier", new DynamicObject[]{dynamicObject}, OperateOption.create());
                }
            } else {
                log.put("pdesc", "失败");
                FacadeHelper.apiLog(log);
                JSONObject faultObject = jsonObject.getJSONObject("error");
                if (faultObject != null) {
                    String faultstring = faultObject.getString("message");
                    if (faultstring.length() > 255) {
                        faultstring = faultstring.substring(0, 255);
                    }
                    dynamicObject.set("qeug_reson", faultstring);//同步失败原因
                    SaveServiceHelper.saveOperate("save", "bd_supplier", new DynamicObject[]{dynamicObject}, OperateOption.create());
                } else {
                    dynamicObject.set("qeug_reson", "未知错误");
                    SaveServiceHelper.saveOperate("save", "bd_supplier", new DynamicObject[]{dynamicObject}, OperateOption.create());
                }
            }
        }
    }

    public synchronized static String getXmlWithoutHeader(SupplierInfo SupplierInfo)
            throws JAXBException, UnsupportedEncodingException {
        JAXBContext context = JAXBContext.newInstance(SupplierInfo.getClass());
        Marshaller marshaller = context.createMarshaller();

        // 启用格式化，并设置两个空格缩进
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty("com.sun.xml.bind.indentString", "  "); // 两个空格缩进

        // 其他配置保持不变
        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-16"); // 注意编码要匹配声明
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
        marshaller.marshal(SupplierInfo, dataStream);
        return dataStream.toString("UTF-16");
    }
}
